import {throttle} from '~utils/optimization.js';
const LOADING = 'loading';
const LOADED = 'loaded';
const ERROR = 'error';
export default {
    install(app, options={}){
        // 资源信息
        const sources = {};
        app.directive('load-lazy', {
            mounted(el, binding){
                const id = (new Date()).getTime();
                el.__id = id;
                el.src = options.loading || '';
                el.setAttribute('lazy', LOADING);
                sources[id] = {
                    el: el,
                    src: binding.value,
                    status: LOADING
                }
                el.onload = () => {
                    el.setAttribute('lazy', LOADED);
                }
                el.onerror = () => {
                    el.setAttribute('lazy', ERROR);
                    el.src = options.error || '';
                }
            },
            updated(el, binding) {
                const id = el.__id;
                el.src = options.loading || '';
                el.setAttribute('lazy', LOADING);
                sources[id] = {
                    ...sources[id],
                    el: el,
                    src: binding.valie,
                    status: LOADING
                }
            }
        });
        app.mixin({
            mounted(){
                if(window.IntersectionObserver){
                    this.io = new IntersectionObserver(entries => {
                        // 获取视口高度
                        const windowHeight = window.innerHeight;
                        entries.forEach(entry => {
                            const source = entry.target.__id && sources[entry.target.__id];
                            // 判断是否有设置资源信息
                            if(!source){
                                return ;
                            }
                            if(top > 0 && top <= windowHeight){
                                entry.target.src = source.src;
                                // 停止监听
                                this.io.unobserve(entry.target);
                                // 删除配置
                                delete sources[entry.__id];
                            }
                        })
                    })
                    return ;
                }
                this.scrollEvent();
                // 绑定事件
                window.addEventListener('scroll', this.scrollEvent);
            },
            beforeUnmount(){
                // 解绑事件
                window.removeEventListener('scroll', scrollEvent);
                delete this.io;
            },
            methods: {
                scrollEvent: throttle(function(){
                    // 获取视口高度
                    const windowHeight = window.innerHeight;
                    for(let k in sources){
                        const {el, src, type} = sources[k];
                        if(type !== LOADING){
                            return ;
                        }
                        const {top} = el.getBoundingClientRect();
                        // 判断是否在可视范围内
                        if(top >=0 && top <= windowHeight){
                            el.setAttribute('src', src);
                            delete sources[k];
                        }
                    }
                })
            }
        })
    }
}